/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  							 script_set_variable.h

	$Header: /heroes4/script_set_variable.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( SCRIPT_SET_VARIABLE_H_INCLUDED )
#define SCRIPT_SET_VARIABLE_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <cassert>
#include <string>

#include "abstract_script_action.h"
#include "abstract_script_expression.h"
#include "owned_ptr.h"
#include "streambuf_operators.h"

// --------------------------------------------------------------------------
// t_script_set_variable class template
// --------------------------------------------------------------------------

template < typename t_expression_arg >
class t_script_set_variable : public t_abstract_script_action
{
public:
	// Types
	typedef t_expression_arg	t_expression;

	// Member functions
	t_expression const &	get_expression() const;
	std::string const &		get_variable_name() const;

	virtual bool			read( std::streambuf& stream, int version );
	virtual bool			read_from_map(
								std::streambuf &	stream,
								int					format_version );
	virtual bool			write( std::streambuf& stream ) const;

private:
	// Data members
	t_counted_ptr< t_expression >	m_expression_ptr;
	std::string						m_variable_name;
};

// --------------------------------------------------------------------------
// t_script_set_variable members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
template < typename t_expression_arg >
inline
typename t_script_set_variable< t_expression_arg >::t_expression const &
t_script_set_variable< t_expression_arg >::get_expression() const
{
	assert( m_expression_ptr.get() != 0 );
	return *m_expression_ptr;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
template < typename t_expression_arg >
inline
std::string const &
t_script_set_variable< t_expression_arg >::get_variable_name() const
{
	return m_variable_name;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
template < typename t_expression_arg >
bool t_script_set_variable< t_expression_arg >::read_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	if( !read_string16( stream, m_variable_name ) )
		return false;

	m_expression_ptr = t_expression::reconstruct_from_map( stream, format_version );
	return m_expression_ptr.get() != 0;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
template < typename t_expression_arg >
bool t_script_set_variable< t_expression_arg >::read( std::streambuf& stream, int version )
{
	if( !read_string16( stream, m_variable_name ) )
		return false;

	m_expression_ptr = t_expression::reconstruct( stream, version );
	return m_expression_ptr.get() != 0;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
template < typename t_expression_arg >
bool t_script_set_variable< t_expression_arg >::write( std::streambuf& stream ) const
{
	if (t_abstract_script_action::write( stream ) == false)
		return false;
	
	if( !write_string16( stream, m_variable_name ) )
		return false;

	m_expression_ptr->write( stream );
	return m_expression_ptr.get() != 0;
}

// --------------------------------------------------------------------------
// t_script_set_numeric_variable type
// --------------------------------------------------------------------------

class t_script_set_numeric_variable 
	: public t_script_set_variable< t_abstract_script_numeric_expression >
{
public:
	virtual void		execute(t_script_context_hero const& context) const;
	virtual void		execute(t_script_context_town const& context) const;
	virtual void		execute(t_script_context_object const& context) const;
	virtual void		execute(t_script_context_army const& context) const;
	virtual void		execute(t_script_context_global const& context) const;
};

SPECIALIZE_SCRIPT_ACTION( k_script_action_set_numeric_variable, t_script_set_numeric_variable );

// --------------------------------------------------------------------------
// t_script_set_boolean_variable type
// --------------------------------------------------------------------------

class t_script_set_boolean_variable 
	: public t_script_set_variable< t_abstract_script_boolean_expression >
{
public:
	virtual void		execute(t_script_context_hero const& context) const;
	virtual void		execute(t_script_context_town const& context) const;
	virtual void		execute(t_script_context_object const& context) const;
	virtual void		execute(t_script_context_army const& context) const;
	virtual void		execute(t_script_context_global const& context) const;
};


SPECIALIZE_SCRIPT_ACTION( k_script_action_set_boolean_variable, t_script_set_boolean_variable );

#endif // !defined( SCRIPT_SET_VARIABLE_H_INCLUDED )
